﻿using LdtJudge.DataEngine.DataBaseStores;
using LdtJudge.DataEngine.Model.ElmentModel;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using System.Xml;

namespace Ldt.WindowsFormsApp
{
    public partial class ShowData : UIForm
    {
        DataContext dynamicData = null;
        List<TreeNode> treeNodes = new List<TreeNode>();
        Dictionary<string, DataTable> dataTablePro = new Dictionary<string, DataTable>();
        Dictionary<string, List<NodeModelList>> caseCauseValueParirsList = new Dictionary<string, List<NodeModelList>>();
        public ShowData(DataContext dataLayerStores)
        {
            InitializeComponent();

            // 将数据结构解析到treeview上，点击结构从数据treeview上查找数据显示到datagridview上
            TreeNode root = new TreeNode();
            root.Text = "根节点";
            dynamicData = dataLayerStores;
            string strJson = JsonConvert.SerializeObject(dataLayerStores.DataLayerAns);
            TreeviewShowJson.BindTreeView(treeViewInfo, strJson);
            treeViewInfo.CollapseAll();

            // 将数据解析到一个treeview上
            TreeNode rootNode = new TreeNode();
            rootNode.Text = "根节点";
            LoopModelToTree(dynamicData, root);
            treeView1.Nodes.Add(root);
            treeView1.CollapseAll();
        }

        /// <summary>
        /// 将解析结果的类解析到树形结构上
        /// </summary>
        /// <param name="objModel"></param>
        /// <param name="node"></param>
        private void LoopModelToTree(object objModel, TreeNode node)
        {
            Type TModel = objModel?.GetType();
            if (TModel != null)
            {
                PropertyInfo[] properties = TModel.GetProperties(BindingFlags.Public | BindingFlags.Instance); // 获取当前type公共属性
                var fields = TModel.GetFields();

                foreach (PropertyInfo propertie in properties)
                {
                    switch (propertie.PropertyType.Name)
                    {
                        case "Double":
                        case "Decimal":
                            object columnValue0 = propertie.GetValue(objModel, null);
                            node.Tag += "\n" + propertie.Name + ":" + Convert.ToString(columnValue0);
                            break;
                        case "Int":
                        case "Nullable`1":
                        case "String":
                            object columnValue = propertie.GetValue(objModel, null);
                            node.Tag += "\n" + propertie.Name + ":" + Convert.ToString(columnValue).Replace(":", "：");
                            break;
                        case "DataTable":
                            TreeNode dtchildnode = new TreeNode();
                            dtchildnode.Text = propertie.Name;
                            if (dataTablePro.ContainsKey(propertie.Name))
                                dataTablePro[propertie.Name] = (DataTable)propertie.GetValue(objModel, null);
                            else
                                dataTablePro.Add(propertie.Name, (DataTable)propertie.GetValue(objModel, null));
                            dtchildnode.Tag = "DT:" + propertie.Name;
                            node.Nodes.Add(dtchildnode);
                            break;
                        case "XmlNode":
                        case "Dictionary`2":
                        case "IDictionary`2":
                            if (propertie.Name == "CaseCauseElementList")
                            {
                                caseCauseValueParirsList = (Dictionary<string, List<NodeModelList>>)propertie.GetValue(objModel, null);
                                TreeNode rootNode = new TreeNode();
                                rootNode.Text = "案由要素结构";
                                foreach (KeyValuePair<string, List<NodeModelList>> item in caseCauseValueParirsList)
                                {
                                    List<NodeModelList> casecauseElementList = item.Value;
                                    foreach (NodeModelList casecauseElement in casecauseElementList)
                                    {
                                        if (!comboBoxPerson.Items.Contains(item.Key + ":" + casecauseElement.NodeModelKey.SP_Name))
                                        {
                                            comboBoxPerson.Items.Add(item.Key + ":" + casecauseElement.NodeModelKey.SP_Name);
                                        }
                                    }
                                }
                            }
                            break;
                        case "XmlDocument":
                            XmlDocument xmldoc = (XmlDocument)propertie.GetValue(objModel, null);
                            if (xmldoc != null)
                                node.Tag += "\n" + propertie.Name + ":" + xmldoc.OuterXml;
                            break;
                        default:
                            if (propertie.PropertyType.IsClass && !propertie.PropertyType.IsGenericType)
                            {
                                if (propertie.PropertyType.Name == "ConfigurationFileModelList")
                                {
                                    continue;
                                }
                                Object ListO = propertie.GetValue(objModel, null);
                                TreeNode childnode = new TreeNode();
                                string tableName = TableNameToCHName(propertie.PropertyType.Name);
                                childnode.Text = tableName;
                                node.Nodes.Add(childnode);
                                LoopModelToTree(ListO, childnode);
                            }
                            else if (propertie.PropertyType.IsGenericType)
                            {
                                if (propertie.Name == "ConfigurationFileModelList")
                                {
                                    continue;
                                }
                                ///如果是泛型集合，进行需要转
                                Object ListO = propertie.GetValue(objModel, null);
                                Type listModel = ListO?.GetType();
                                int count = Convert.ToInt32(listModel?.GetProperty("Count").GetValue(ListO, null));
                                for (int i = 0; i < count; i++)
                                {
                                    //将泛型集合的数据转对象集合，然后依次获取下标；
                                    object listItem = listModel.GetProperty("Item").GetValue(ListO, new object[] { i });

                                    string tableName = TableNameToCHName(propertie.Name);
                                    TreeNode childnode = new TreeNode();
                                    childnode.Text = tableName;// TableNameToCHName(propertie.Name);
                                    if (!node.Nodes.ContainsKey(tableName))
                                    {
                                        node.Nodes.Add(childnode);
                                    }
                                    LoopModelToTree(listItem, childnode);
                                }
                            }
                            break;
                    }
                }
            }
        }

        /// <summary>
        /// 设计的表名转成中文释义方便使用者理解
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <returns></returns>
        private string TableNameToCHName(string tableName)
        {
            string CHName = "";
            switch (tableName)
            {
                case "AnalysisParameterModel":
                    CHName = "分析要素";
                    break;
                case "SourceDossierInfosModel":
                    CHName = "卷宗信息";
                    break;
                case "CaseEntityInfoList":
                    CHName = "案件关联实体信息列表";
                    break;
                case "EntityRoleList":
                    CHName = "实体角色信息列表";
                    break;
                case "SpokeParagraphTxtList":
                    CHName = "发言对话内容列表";
                    break;
                case "SD_ParagraphTXTList":
                    CHName = "文书段落内容列表";
                    break;
                case "SpokeTextDialogue":
                    CHName = "人员对话内容列表";
                    break;
                case "CaseCausesList":
                    CHName = "案由信息";
                    break;
                default:
                    CHName = tableName;
                    break;
            }
            return CHName;
        }

        /// <summary>
        /// 点击节点显示当前节点的信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeViewInfo_AfterSelect(object sender, TreeViewEventArgs e)
        {
            //if (e.Node.Parent != null)
            //{
            dGVData.DataSource = "";
            string nodePath = "根节点\\" + e.Node.FullPath;
            List<TreeNode> nodeList = new List<TreeNode>();
            GetNodes(treeView1.Nodes[0], nodePath, ref nodeList);

            if (nodeList.Count > 0)
            {
                #region 创建DT
                DataTable dt = new DataTable();
                if (nodeList[0].Tag.ToString().StartsWith("DT:"))
                {
                    string keyName = nodeList[0].Tag.ToString().Split(':')[1];
                    if (dataTablePro.ContainsKey(keyName))
                    {
                        dt = dataTablePro[keyName];
                    }
                }
                else
                {
                    if (dt.Columns.Count == 0)
                    {
                        string[] columns = nodeList[0].Tag.ToString().Split('\n');
                        foreach (string column in columns)
                        {
                            if (column.IndexOf(":") > -1)
                            {
                                dt.Columns.Add(GetCloumnCHName(column.Split(':')[0]));
                            }
                        }
                    }
                    #endregion

                    #region 按行添加数据
                    foreach (TreeNode node in nodeList)
                    {
                        DataRow dr;
                        dr = dt.NewRow();
                        foreach (string col in node.Tag.ToString().Split('\n'))
                        {
                            if (col.IndexOf(":") > -1)
                            {
                                if (dt.Columns.Contains(GetCloumnCHName(col.Split(':')[0])))
                                {
                                    dr[GetCloumnCHName(col.Split(':')[0])] = col.Split(':')[1];
                                }
                            }
                        }
                        dt.Rows.Add(dr);
                    }
                    #endregion
                }

                // 使用GridView显示dataTable
                dGVData.DataSource = dt;
            }
            //}
        }

        private void GetNode(string key, List<object> nodes)
        {
            Type TModel = dynamicData?.GetType();
        }

        /// <summary>
        /// 通过fullpath 查找treeview节点 节点name属性需要赋过值
        /// </summary>
        /// <param name="nodes">TreeNodeCollection node集合</param>
        /// <param name="fullPath">要查找的节点的fullPath</param>
        /// <returns></returns>
        private void GetNodes(TreeNode node, string full_path, ref List<TreeNode> re)
        {
            foreach (TreeNode temp in node.Nodes)
            {
                if (string.Equals(temp.FullPath, full_path))
                {
                    re.Add(temp);
                }
                if (temp.Nodes.Count != 0)
                {
                    GetNodes(temp, full_path, ref re);
                }
            }
        }

        /// <summary>
        /// 获取字段的中文释义
        /// </summary>
        /// <param name="cloumnName"></param>
        /// <returns></returns>
        private string GetCloumnCHName(string cloumnName)
        {
            string chName = "";
            string exePath = Application.StartupPath;
            string jsonStr = GetFileJson(exePath + @"\cloumnName.json");
            JObject jo = (JObject)JsonConvert.DeserializeObject(jsonStr);
            foreach (var item in jo)
            {
                JObject tb = (JObject)JsonConvert.DeserializeObject(item.Value.ToString());
                foreach (var cloumn in tb)
                {
                    if (cloumn.Key == cloumnName.ToLower())
                    {
                        chName = cloumn.Value.ToString();
                        break;
                    }
                }
            }
            if (string.IsNullOrEmpty(chName))
            {
                chName = cloumnName;
            }
            return chName;
        }

        /// <summary>
        /// 读取json文件，返回json字符串
        /// </summary>
        /// <param name="filepath">json文件</param>
        /// <returns></returns>
        public static string GetFileJson(string filepath)
        {
            string json = string.Empty;
            using (FileStream fs = new FileStream(filepath, FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite))
            {
                using (StreamReader sr = new StreamReader(fs, Encoding.GetEncoding("utf-8")))
                {
                    json = sr.ReadToEnd().ToString();
                }
            }
            return json;
        }

        /// <summary>
        /// 在richText中显示dataGridView选中行的具体内容
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dGVData_SelectionChanged(object sender, EventArgs e)
        {
            richTextBoxRowInfo.Text="";
            DataGridViewRow row = dGVData.CurrentRow;
            if (row != null)
            {
                DataRow dr = (row.DataBoundItem as DataRowView).Row;

                string rowData = "";
                foreach (DataGridViewColumn column in dGVData.Columns)
                {
                    if (string.IsNullOrWhiteSpace(rowData))
                    {
                        rowData = column.Name + ":" + dr[column.Name].ToString();
                    }
                    else
                    {
                        rowData += System.Environment.NewLine + column.Name + ":" + dr[column.Name].ToString();
                    }
                }
                richTextBoxRowInfo.AppendText(rowData);
            }
        }

        /// <summary>
        /// 将节点加载到树上
        /// </summary>
        /// <param name="parentNode">父节点</param>
        /// <param name="nodes">节点</param>
        private void UploadTreeView(TreeNode parentNode, List<NodeModelList> nodes)
        {
            foreach (NodeModelList item in nodes)
            {
                List<NodeModel> nodeModelList = item.BeforeMergerListModels;
                foreach (NodeModel node in nodeModelList)
                {
                    string[] pathNodesF = node.NodePath.Split('/');
                    List<string> pathNodes = new List<string>();
                    foreach (string items in pathNodesF)
                    {
                        if (!string.IsNullOrEmpty(items))
                            pathNodes.Add(items);
                    }

                    List<TreeNode> parentNodes = new List<TreeNode>();
                    for (int loop = 0; loop < pathNodes.Count; loop++)
                    {
                        // 获取父节点path
                        string parentPath = string.Empty;
                        if (loop > 0)
                        {
                            // 查找父节点
                            parentPath = pathNodes[loop - 1];
                            parentNodes = FindNodeByName(parentNodes, parentPath);
                            if (parentNodes.Count > 0)
                            {
                                List<TreeNode> parentNodesCopy = new List<TreeNode>();
                                // 遍历父节点查看是否有当前节点，有的话将当前节点变成父节点再次循环
                                foreach (TreeNode pNode in parentNodes)
                                {
                                    TreeNode[] ctreeNodes = new TreeNode[pNode.Nodes.Count];
                                    pNode.Nodes.CopyTo(ctreeNodes, 0);
                                    if (FindNodeByName(ctreeNodes.ToList(), pathNodes[loop]).Count > 0)
                                    {
                                        parentNodesCopy.AddRange(FindNodeByName(ctreeNodes.ToList(), pathNodes[loop]));
                                    }
                                    else
                                    {
                                        TreeNode currentNode = new TreeNode();
                                        int arrLen = pathNodes[loop].Split('/').Length;
                                        currentNode = new TreeNode();
                                        currentNode.Name = pathNodes[loop].Split('/')[arrLen - 1];
                                        currentNode.Text = pathNodes[loop].Split('/')[arrLen - 1];
                                        string extTxt = string.Join("  ", node.ExtOriginalText.ToList().ToArray());
                                        currentNode.Tag = "orgTxt:" + node.OriginalText + "-ruleCode:" + node.ElementCommWhere.RegexCode + "-extTxt:" + extTxt;
                                        pNode.Nodes.Add(currentNode);
                                        parentNodesCopy.Add(currentNode);
                                    }
                                }
                                parentNodes = parentNodesCopy;
                            }
                        }
                        else
                        {
                            TreeNode[] ptreeNodes = new TreeNode[parentNode.Nodes.Count];
                            parentNode.Nodes.CopyTo(ptreeNodes, 0);
                            if (FindNodeByName(ptreeNodes.ToList(), pathNodes[loop]).Count == 0)
                            {
                                TreeNode currentNode = new TreeNode();
                                int arrLen = pathNodes[loop].Split('/').Length;
                                currentNode = new TreeNode();
                                currentNode.Name = pathNodes[loop].Split('/')[arrLen - 1];
                                currentNode.Text = pathNodes[loop].Split('/')[arrLen - 1];
                                string extTxt = string.Join("  ", node.ExtOriginalText.ToList().ToArray());
                                currentNode.Tag = "orgTxt:" + node.OriginalText + "-ruleCode:" + node.ElementCommWhere.RegexCode + "-extTxt:" + extTxt;
                                parentNode.Nodes.Add(currentNode);
                                parentNodes.Add(currentNode);
                            }
                            else
                            {
                                parentNodes = FindNodeByName(ptreeNodes.ToList(), pathNodes[loop]);
                            }
                        }
                    }
                }
            }
        }

        public List<TreeNode> FindNodeByName(List<TreeNode> nodes, string name)
        {
            List<TreeNode> re = new List<TreeNode>();
            re = nodes.Where(a => a.Name == name).ToList();
            return re;
        }
        /// <summary>
        /// 通过fullpath 查找treeview节点 节点name属性需要赋过值
        /// </summary>
        /// <param name="nodes">TreeNodeCollection node集合</param>
        /// <param name="fullPath">要查找的节点的fullPath</param>
        /// <returns></returns>
        TreeNode GetNodeNew(List<TreeNode> nodes, string fullPath)
        {

            string[] paths = fullPath.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
            TreeNode tn = null;
            for (int i = 0; i < paths.Length; i++)
            {
                var finds = nodes.Where(a => a.Name == paths[i]).ToList();//Find(paths[i], false);
                if (finds.Count > 0)
                {
                    if (i < paths.Length - 1)
                    {
                        string[] tempArr = new string[paths.Length - i - 1];
                        Array.Copy(paths, i + 1, tempArr, 0, paths.Length - i - 1);
                        string fuPath = string.Join("/", tempArr);
                        foreach (TreeNode item in finds)
                        {
                            TreeNode[] treeNodes = new TreeNode[item.Nodes.Count];
                            item.Nodes.CopyTo(treeNodes, 0);
                            GetNodeNew(treeNodes.ToList(), fuPath);
                        }
                    }
                    else
                    {
                        tn = finds[0];
                        break;
                    }

                }
                else
                {
                    break;
                }
            }
            return tn;
        }

        /// <summary>
        /// 路径切片组合
        /// </summary>
        /// <param name="path">路径</param>
        /// <returns></returns>
        public string[] cutPath(string path)
        {
            string[] nodelist = path.Replace("/", "-").Split('-');
            string[] nodepath = new string[nodelist.Length];
            for (int loops = 1; loops <= nodelist.Length; loops++)
            {
                string[] temparr = new string[loops];
                Array.Copy(nodelist, 0, temparr, 0, loops);
                string tempstr = string.Join("/", temparr);
                nodepath[loops - 1] = tempstr;
            }
            if (string.IsNullOrEmpty(nodepath[0]))
            {
                string[] re = new string[nodelist.Length - 1];
                Array.Copy(nodepath, 1, re, 0, re.Length);
                return re;
            }
            else
            {
                return nodepath;
            }
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            MessageBox.Show(e.Node.Tag.ToString());
        }

        /// <summary>
        /// 下拉框改变事件
        /// </summary>
        /// <param name="sender">发送方</param>
        /// <param name="e">参数</param>
        private void comboBoxPerson_SelectedIndexChanged(object sender, EventArgs e)
        {
            treeViewElement.Nodes.Clear();
            string[] currentItems = comboBoxPerson.SelectedItem.ToString().Split(':');
            List<NodeModelList> nodeModelLists = caseCauseValueParirsList[currentItems[0]];
            TreeNode rootNode = new TreeNode();
            rootNode.Text = currentItems[0];
            List<NodeModelList> personNodeModelLists = new List<NodeModelList>();
            personNodeModelLists = nodeModelLists.Where(a => a.NodeModelKey.SP_Name == currentItems[1]).ToList();
            UploadTreeView(rootNode, personNodeModelLists);
            treeViewElement.Nodes.Add(rootNode);
            treeViewElement.CollapseAll();
        }

        private void treeViewElement_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (e.Node.Tag.ToString().IndexOf("-") > -1)
            {
                string[] content = e.Node.Tag.ToString().Split('-');
                foreach (string item in content)
                {
                    if (item.IndexOf(":") > -1)
                    {
                        string key = item.Split(':')[0];
                        string value = item.Split(':')[1];
                        switch (key)
                        {
                            case "orgTxt":
                                richTextBoxOrgText.Text = value;
                                break;
                            case "ruleCode":
                                textBoxrule.Text = value;
                                break;
                            case "extTxt":
                                richTextBoxExtValue.Text = value;
                                break;
                            default:
                                break;
                        }
                    }
                }
            }
        }
    }

}
